// DecisionUtils.java
package org.zjx.util;

import org.zjx.core.DecisionContext;
import org.zjx.core.DecisionNode;
import org.zjx.core.nodes.*;

import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;

/**
 * 决策工具类 - 提供创建常见决策节点模式的实用方法
 *
 * 这个工具类封装了创建复杂决策节点模式的工厂方法，
 * 简化了决策树的构建过程。
 */
public final class DecisionUtils {
    // 私有构造器防止实例化，因为这是一个纯工具类
    private DecisionUtils() {}

    /**
     * 创建条件分支节点
     *
     * @param condition 决定分支走向的条件谓词
     * @param trueBranch 条件为true时执行的分支节点
     * @param falseBranch 条件为false时执行的分支节点
     * @return 组合了条件和分支的决策节点
     */
    public static DecisionNode ifThenElse(
            Predicate<DecisionContext> condition,
            DecisionNode trueBranch,
            DecisionNode falseBranch
    ) {
        return new ConditionNode(
                (accessor, params) -> {
                    // 将StateAccessor和参数包装成DecisionContext
                    DecisionContext ctx = new DecisionContext(accessor, params);
                    return condition.test(ctx);
                },
                trueBranch,
                falseBranch
        );
    }

    /**
     * 创建顺序节点
     *
     * @param nodes 要按顺序执行的决策节点数组
     * @return 组合了所有节点的顺序决策节点
     */
    public static DecisionNode sequence(DecisionNode... nodes) {
        return new SequenceNode(List.of(nodes));
    }

    /**
     * 创建并行节点
     *
     * @param nodes 要并行执行的决策节点数组
     * @return 组合了所有节点的并行决策节点
     */
    public static DecisionNode parallel(DecisionNode... nodes) {
        return new ParallelNode(List.of(nodes));
    }

    /**
     * 创建循环节点
     *
     * @param body 循环体节点
     * @param condition 控制循环继续的条件谓词
     * @return 组合了循环体和条件的循环决策节点
     */
    public static DecisionNode loop(
            DecisionNode body,
            Predicate<DecisionContext> condition
    ) {
        return new LoopNode(
                body,
                ctx -> condition.test(new DecisionContext(
                        ctx.getStateAccessor(),
                        ctx.getLocalParams()
                ))
        );
    }
}